剑指 Offer 30. 包含min函数的栈

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

1
2
3
4
5
6
7
8
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.

提示:

  1. 各函数的调用总次数不超过 20000 次

注意:本题与主站 155 题相同:https://leetcode-cn.com/problems/min-stack/


算法

(单调栈) $O(1)$

用一个栈 stk 维护基本的栈操作,同时需要维护一个单调栈 min_stk,用来返回栈中的最小值

  1. push(x): 压入 x 到基本栈 stk,同时判断单调栈 min_stk 是否为空或当前元素 x 是否小于等于当前栈顶元素,如果是,同样将 x 压入到单调栈中

    这里为什么相等也要入栈,是因为在 pop 的时候我们判断的条件就是如果两个栈顶相等,min_stk 也要弹出元素,所以 min_stk 中要压入 x,否则如果 stk 的最小值为有多个相等的值 x,那么 stk 和 min_stk 都弹出 x 之后,此时 stk 的最小值仍然是 x,但 min_stk 的栈顶一定小于 x,与答案不符,所以必须要压入 x

  2. pop(): 在基本栈 stk 弹出之前,需要判断 stk 的栈顶和 min_stk 的栈顶是否相等,如果相等 min_stk 也要弹出栈顶
  3. top(): stk.top()
  4. getMin(): min_stk.top()

时间复杂度

四个操作都只有常数次入栈出栈操作,所以时间复杂度是 $O(1)$

空间复杂度

$O(n)$

C++ 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class MinStack {
public:
stack<int> stk, min_stk;

/** initialize your data structure here. */
MinStack() {

}

void push(int x) {
stk.push(x);
if (min_stk.empty() || min_stk.top() >= x) min_stk.push(x);
}

void pop() {
int t = stk.top();
stk.pop();
if (t == min_stk.top()) min_stk.pop();
}

int top() {
return stk.top();
}

int min() {
return min_stk.top();
}
};

/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
Author: tonngw
Link: https://tonngw.com/2022/07/08/剑指 Offer/剑指 Offer 30. 包含min函数的栈/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.